/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package com.cloud.control.service.core;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Timer;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cloud.control.service.socket.codes.ProxyCodecFactory;
import com.cloud.control.service.socket.handler.ProxyProtocolHandler;
import com.cloud.control.service.utils.JDBCUtils;


/**
 * (<b>Entry point</b>) 这个程序是TCP服务器，监听proxy和sender的连入请求，进行身份
 * 验证，然后把适当的proxy分配给sender！
 *
 * 监听端口9180
 * @author
 */
public class TCPProxyManager {

    /** Set this to true if you want to make the server SSL */
    private static final boolean USE_SSL = false;
    private final static Log log = LogFactory.getLog(TCPProxyManager.class);
    private final Timer taskTimer=new Timer();

    public static void main(String[] args) throws Exception {
    	/**数据库中load全部有效用户!**/
    	JDBCUtils.loadEncryptedUsers();
      /**  NioSocketAcceptor acceptor = new NioSocketAcceptor();
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        //To decode IP message from
        acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ProxyCodecFactory(false)));

        acceptor.setHandler(new ProxyProtocolHandler());
        acceptor.bind(new InetSocketAddress(9180));

        log.error("Listening on port " + 9180);**/
    	TCPProxyManager manager=new TCPProxyManager();
    	manager.run();
    	
    }
    public TCPProxyManager(){
    	
    }
    
    public void run(){
    	
        try {
        	UsrValidationTask task =new UsrValidationTask();
        	//启动开始执行，每1 hour 扫描一次内存,加载有效的加密用户!尽快执行,避免proxies无法校验
        	taskTimer.schedule(task,0, 15*60*1000);    		
			NioSocketAcceptor acceptor = new NioSocketAcceptor();
			DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
			
			//ProxyCodecFactory 专门用于解析代理协议
			acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ProxyCodecFactory(false)));
			 			
			// Add SSL filter if SSL is enabled.
			if (USE_SSL) {
			    addSSLSupport(chain);
			}

			addLogger(chain);
			// Bind
			acceptor.setHandler(new ProxyProtocolHandler());
			acceptor.getSessionConfig().setReadBufferSize( 2048 );
			acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
			
			acceptor.bind(new InetSocketAddress(9180));

			log.info("TCP Server Listening on port: 9180" );
		} catch (IOException e) {
			log.error("Init IOException Error = ",e.getCause());
			taskTimer.cancel();
			System.exit(0);
		} catch (Exception e) {
			log.error("Init Exception Error = ",e.getCause());
			taskTimer.cancel();
			System.exit(9);
		}
    	
    }
    private  void addSSLSupport(DefaultIoFilterChainBuilder chain)
            throws Exception {
        //SslFilter sslFilter = new SslFilter(BogusSslContextFactory.getInstance(true));
        //chain.addLast("sslFilter", sslFilter);
    	log.info("SSL ON");
    }

    private  void addLogger(DefaultIoFilterChainBuilder chain)
            throws Exception {
        chain.addLast("logger", new LoggingFilter());
        log.info("Logging ON");
    }
	

	

}
